package de.elmar_baumann.nb.slclock.alarmclock;

import de.elmar_baumann.nb.slclock.util.ArrayUtil;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.ListCellRenderer;

/**
 * @author Elmar Baumann
 */
public class AlarmEventEditPanel extends javax.swing.JPanel {

    private static final long serialVersionUID = 1L;
    private final AlarmEvent event;
    private final Map<JCheckBox, DayOfWeek> daysOfWeekCheckBoxes = new HashMap<>();

    public AlarmEventEditPanel() {
        this(createCurrentEvent());
    }

    private static AlarmEvent createCurrentEvent() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        return new AlarmEvent(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
    }

    public AlarmEventEditPanel(AlarmEvent event) {
        this.event = event;
        initComponents();
        initCheckBoxesOfDaysOfWeekMap();
        initComboBoxes();
        eventToGui();
    }

    private void initCheckBoxesOfDaysOfWeekMap() {
        daysOfWeekCheckBoxes.put(checkBoxMonday, DayOfWeek.MONDAY);
        daysOfWeekCheckBoxes.put(checkBoxTuesday, DayOfWeek.TUESDAY);
        daysOfWeekCheckBoxes.put(checkBoxWednesday, DayOfWeek.WEDNESDAY);
        daysOfWeekCheckBoxes.put(checkBoxThursday, DayOfWeek.THURSDAY);
        daysOfWeekCheckBoxes.put(checkBoxFriday, DayOfWeek.FRIDAY);
        daysOfWeekCheckBoxes.put(checkBoxSaturday, DayOfWeek.SATURDAY);
        daysOfWeekCheckBoxes.put(checkBoxSunday, DayOfWeek.SUNDAY);
    }

    private void initComboBoxes() {
        comboBoxHour.setModel(new DefaultComboBoxModel<>(ArrayUtil.createIntRegionArray(0, 23)));
        comboBoxMinute.setModel(new DefaultComboBoxModel<>(ArrayUtil.createIntRegionArray(0, 59)));
    }

    private void eventToGui() {
        comboBoxHour.setSelectedItem(event.getHour());
        comboBoxMinute.setSelectedItem(event.getMinute());
        checkBoxSound.setSelected(event.isSound());
        checkBoxVerbose.setSelected(event.isVerbose());
        textFieldDisplayName.setText(event.getDisplayName() == null ? "" : event.getDisplayName());
        Collection<DayOfWeek> eventDaysOfWeek = event.getDaysOfWeek();
        for (JCheckBox checkBox : daysOfWeekCheckBoxes.keySet()) {
            DayOfWeek cbDayOfWeek = daysOfWeekCheckBoxes.get(checkBox);
            checkBox.setSelected(eventDaysOfWeek.contains(cbDayOfWeek));
        }
    }

    public AlarmEvent save() {
        event.setDisplayName(textFieldDisplayName.getText().trim());
        event.setHour((int) comboBoxHour.getSelectedItem());
        event.setMinute((int) comboBoxMinute.getSelectedItem());
        event.setSound(checkBoxSound.isSelected());
        event.setVerbose(checkBoxVerbose.isSelected());
        Collection<DayOfWeek> daysOfWeek = new ArrayList<>(7);
        for (JCheckBox checkBox : daysOfWeekCheckBoxes.keySet()) {
            if (checkBox.isSelected()) {
                daysOfWeek.add(daysOfWeekCheckBoxes.get(checkBox));
            }
        }
        event.setDaysOfWeek(daysOfWeek);
        return event;
    }

    private final ListCellRenderer<Integer> timeUnitRenderer = new ListCellRenderer<Integer>() {

        private final DefaultListCellRenderer delegate = new DefaultListCellRenderer();

        @Override
        public Component getListCellRendererComponent(JList<? extends Integer> list, Integer value, int index, boolean isSelected, boolean cellHasFocus) {
            String timeUnit = String.format("%02d", value);
            return delegate.getListCellRendererComponent(list, timeUnit, index, isSelected, cellHasFocus);
        }
    };

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    private void initComponents() {//GEN-BEGIN:initComponents

        labelDisplayName = new javax.swing.JLabel();
        textFieldDisplayName = new javax.swing.JTextField();
        labelTime = new javax.swing.JLabel();
        comboBoxHour = new javax.swing.JComboBox<>();
        labelHourMinuteDelimiter = new javax.swing.JLabel();
        comboBoxMinute = new javax.swing.JComboBox<>();
        checkBoxSound = new javax.swing.JCheckBox();
        checkBoxVerbose = new javax.swing.JCheckBox();
        panelDaysOfWeek = new javax.swing.JPanel();
        checkBoxMonday = new javax.swing.JCheckBox();
        checkBoxTuesday = new javax.swing.JCheckBox();
        checkBoxWednesday = new javax.swing.JCheckBox();
        checkBoxThursday = new javax.swing.JCheckBox();
        checkBoxFriday = new javax.swing.JCheckBox();
        checkBoxSaturday = new javax.swing.JCheckBox();
        checkBoxSunday = new javax.swing.JCheckBox();

        labelDisplayName.setLabelFor(textFieldDisplayName);
        org.openide.awt.Mnemonics.setLocalizedText(labelDisplayName, org.openide.util.NbBundle.getMessage(AlarmEventEditPanel.class, "AlarmEventEditPanel.labelDisplayName.text")); // NOI18N

        textFieldDisplayName.setColumns(15);

        labelTime.setLabelFor(comboBoxHour);
        org.openide.awt.Mnemonics.setLocalizedText(labelTime, org.openide.util.NbBundle.getMessage(AlarmEventEditPanel.class, "AlarmEventEditPanel.labelTime.text")); // NOI18N

        comboBoxHour.setRenderer(timeUnitRenderer);

        org.openide.awt.Mnemonics.setLocalizedText(labelHourMinuteDelimiter, ":"); // NOI18N

        comboBoxMinute.setRenderer(timeUnitRenderer);

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxSound, org.openide.util.NbBundle.getMessage(AlarmEventEditPanel.class, "AlarmEventEditPanel.checkBoxSound.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxVerbose, org.openide.util.NbBundle.getMessage(AlarmEventEditPanel.class, "AlarmEventEditPanel.checkBoxVerbose.text")); // NOI18N

        panelDaysOfWeek.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AlarmEventEditPanel.class, "AlarmEventEditPanel.panelDaysOfWeek.border.title"))); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxMonday, DayOfWeek.MONDAY.getGuiString());

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxTuesday, DayOfWeek.TUESDAY.getGuiString());

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxWednesday, DayOfWeek.WEDNESDAY.getGuiString());

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxThursday, DayOfWeek.THURSDAY.getGuiString());

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxFriday, DayOfWeek.FRIDAY.getGuiString());

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxSaturday, DayOfWeek.SATURDAY.getGuiString());

        org.openide.awt.Mnemonics.setLocalizedText(checkBoxSunday, DayOfWeek.SUNDAY.getGuiString());

        javax.swing.GroupLayout panelDaysOfWeekLayout = new javax.swing.GroupLayout(panelDaysOfWeek);
        panelDaysOfWeek.setLayout(panelDaysOfWeekLayout);
        panelDaysOfWeekLayout.setHorizontalGroup(
            panelDaysOfWeekLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelDaysOfWeekLayout.createSequentialGroup()
                .addGroup(panelDaysOfWeekLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(checkBoxMonday)
                    .addComponent(checkBoxTuesday)
                    .addComponent(checkBoxWednesday)
                    .addComponent(checkBoxThursday))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(panelDaysOfWeekLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(checkBoxFriday)
                    .addComponent(checkBoxSaturday)
                    .addComponent(checkBoxSunday))
                .addGap(0, 0, Short.MAX_VALUE))
        );
        panelDaysOfWeekLayout.setVerticalGroup(
            panelDaysOfWeekLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelDaysOfWeekLayout.createSequentialGroup()
                .addGroup(panelDaysOfWeekLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(checkBoxMonday)
                    .addComponent(checkBoxFriday))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(panelDaysOfWeekLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(checkBoxTuesday)
                    .addComponent(checkBoxSaturday))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(panelDaysOfWeekLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(checkBoxWednesday)
                    .addComponent(checkBoxSunday))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxThursday))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(panelDaysOfWeek, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(labelDisplayName)
                            .addComponent(labelTime))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(textFieldDisplayName)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(comboBoxHour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(labelHourMinuteDelimiter)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(comboBoxMinute, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(checkBoxVerbose)
                                    .addComponent(checkBoxSound))
                                .addGap(0, 0, Short.MAX_VALUE)))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(labelDisplayName)
                    .addComponent(textFieldDisplayName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(labelTime)
                    .addComponent(comboBoxHour, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(comboBoxMinute, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(checkBoxSound)
                    .addComponent(labelHourMinuteDelimiter))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(checkBoxVerbose)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(panelDaysOfWeek, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox checkBoxFriday;
    private javax.swing.JCheckBox checkBoxMonday;
    private javax.swing.JCheckBox checkBoxSaturday;
    private javax.swing.JCheckBox checkBoxSound;
    private javax.swing.JCheckBox checkBoxSunday;
    private javax.swing.JCheckBox checkBoxThursday;
    private javax.swing.JCheckBox checkBoxTuesday;
    private javax.swing.JCheckBox checkBoxVerbose;
    private javax.swing.JCheckBox checkBoxWednesday;
    private javax.swing.JComboBox<Integer> comboBoxHour;
    private javax.swing.JComboBox<Integer> comboBoxMinute;
    private javax.swing.JLabel labelDisplayName;
    private javax.swing.JLabel labelHourMinuteDelimiter;
    private javax.swing.JLabel labelTime;
    private javax.swing.JPanel panelDaysOfWeek;
    private javax.swing.JTextField textFieldDisplayName;
    // End of variables declaration//GEN-END:variables

}
